"""
Shopify集成服务模块
负责处理Shopify店铺的注册、webhook事件处理等集成功能
"""
from sqlmodel import Session, select
from typing import Dict, Any, List, Optional
import requests
import json
import hmac
import hashlib
import logging
from datetime import datetime
from app.models.order_models import ShopifyStore, Order, OrderStatus, PaymentStatus
from app.services.order_service import OrderService

logger = logging.getLogger(__name__)


class ShopifyService:
    """
    Shopify服务类
    处理与Shopify平台的交互，包括店铺注册、webhook处理等功能
    """
    
    def __init__(self, db: Session):
        """
        初始化Shopify服务
        
        Args:
            db (Session): 数据库会话对象
        """
        self.db = db
    
    def register_shopify_store(self, store_data: Dict[str, Any]) -> ShopifyStore:
        """
        注册Shopify店铺
        验证店铺访问权限并保存店铺信息
        
        Args:
            store_data (Dict[str, Any]): 店铺注册数据
            
        Returns:
            ShopifyStore: 创建的店铺对象
            
        Raises:
            ValueError: 当无法访问Shopify店铺API时抛出
            Exception: 当注册失败时抛出
        """
        try:
            # 验证店铺访问权限
            if not self._verify_shopify_access(store_data):
                raise ValueError("无法访问Shopify店铺API")
            
            # 创建店铺记录
            store = ShopifyStore(
                store_name=store_data["store_name"],
                shopify_domain=store_data["shopify_domain"],
                api_key=store_data["api_key"],
                api_secret=store_data["api_secret"],
                access_token=store_data.get("access_token")
            )
            
            # 保存到数据库
            self.db.add(store)
            self.db.commit()
            self.db.refresh(store)
            
            # 设置webhook
            self._setup_webhooks(store)
            
            return store
            
        except Exception as e:
            # 出现异常时回滚数据库事务
            self.db.rollback()
            logger.error(f"注册Shopify店铺失败: {str(e)}")
            raise
    
    def _verify_shopify_access(self, store_data: Dict[str, Any]) -> bool:
        """
        验证Shopify店铺访问权限
        通过访问Shopify店铺API来验证访问令牌是否有效
        
        Args:
            store_data (Dict[str, Any]): 店铺数据，包含域名和访问令牌
            
        Returns:
            bool: 验证结果，有效返回True
        """
        try:
            # 构建Shopify店铺API请求URL
            url = f"https://{store_data['shopify_domain']}/admin/api/2023-01/shop.json"
            headers = {
                'X-Shopify-Access-Token': store_data.get('access_token', ''),
                'Content-Type': 'application/json'
            }
            
            # 发送请求并检查响应状态
            response = requests.get(url, headers=headers)
            return response.status_code == 200
        except Exception:
            # 发生异常视为验证失败
            return False
    
    def _setup_webhooks(self, store: ShopifyStore):
        """
        为Shopify店铺设置webhook
        配置订单相关事件的通知
        
        Args:
            store (ShopifyStore): 店铺对象
        """
        # webhook接收地址
        webhook_url = "https://your-domain.com/api/shopify/webhook"
        # 需要监听的webhook事件类型
        webhook_topics = [
            "orders/create",      # 订单创建
            "orders/updated",     # 订单更新
            "orders/paid",        # 订单支付
            "orders/fulfilled"    # 订单发货
        ]
        
        # 为每种事件类型创建webhook
        for topic in webhook_topics:
            webhook_data = {
                "webhook": {
                    "topic": topic,
                    "address": webhook_url,
                    "format": "json"
                }
            }
            
            try:
                self._make_shopify_request(
                    store, 
                    "POST", 
                    "/admin/api/2023-01/webhooks.json",
                    webhook_data
                )
            except Exception as e:
                logger.warning(f"设置webhook失败 {topic}: {str(e)}")
    
    def process_shopify_webhook(self, store_domain: str, topic: str, data: Dict[str, Any]) -> bool:
        """
        处理Shopify webhook事件
        根据事件类型调用对应的处理方法
        
        Args:
            store_domain (str): 店铺域名
            topic (str): webhook事件类型
            data (Dict[str, Any]): webhook数据
            
        Returns:
            bool: 处理结果
        """
        try:
            # 验证webhook签名
            if not self._verify_webhook_signature(store_domain, data):
                logger.error("Webhook签名验证失败")
                return False
            
            # 根据事件类型调用对应处理方法
            if topic == "orders/create":
                return self._handle_order_create(store_domain, data)
            elif topic == "orders/paid":
                return self._handle_order_paid(store_domain, data)
            elif topic == "orders/fulfilled":
                return self._handle_order_fulfilled(store_domain, data)
            elif topic == "orders/updated":
                return self._handle_order_updated(store_domain, data)
            
            return True
            
        except Exception as e:
            logger.error(f"处理Shopify webhook失败: {str(e)}")
            return False
    
    def _handle_order_create(self, store_domain: str, data: Dict[str, Any]) -> bool:
        """
        处理订单创建事件
        将Shopify订单同步到本地系统
        
        Args:
            store_domain (str): 店铺域名
            data (Dict[str, Any]): 订单数据
            
        Returns:
            bool: 处理结果
        """
        order_data = data.get("order", {})
        
        # 检查订单是否已存在
        existing_order = self.db.exec(
            select(Order).where(Order.shopify_order_id == str(order_data["id"]))
        ).first()
        
        if existing_order:
            logger.info(f"Shopify订单已存在: {order_data['id']}")
            return True
        
        # 创建订单服务实例
        order_service = OrderService(self.db)
        
        try:
            # 创建本地订单记录
            local_order = order_service.create_order({
                "user_id": 1,  # 默认用户ID
                "total_amount": float(order_data.get("total_price", 0)),  # 订单总金额
                "shopify_order_id": str(order_data["id"]),  # Shopify订单ID
                "shopify_order_data": order_data  # 完整订单数据
            })
            
            logger.info(f"成功创建本地订单: {local_order.order_number}")
            return True
            
        except Exception as e:
            logger.error(f"创建本地订单失败: {str(e)}")
            return False
    
    def _handle_order_paid(self, store_domain: str, data: Dict[str, Any]) -> bool:
        """
        处理订单支付事件
        更新订单状态并触发生产流程
        
        Args:
            store_domain (str): 店铺域名
            data (Dict[str, Any]): 订单数据
            
        Returns:
            bool: 处理结果
        """
        order_data = data.get("order", {})
        
        # 查询对应的本地订单
        order = self.db.exec(
            select(Order).where(Order.shopify_order_id == str(order_data["id"]))
        ).first()
        
        if order:
            # 更新订单状态为已支付
            order.payment_status = PaymentStatus.SUCCESS
            order.status = OrderStatus.PAID
            order.updated_at = datetime.utcnow()
            
            self.db.commit()
            
            # 触发生产流程
            self._trigger_production(order)
            
            logger.info(f"Shopify订单支付成功: {order.order_number}")
        
        return True
    
    def _handle_order_fulfilled(self, store_domain: str, data: Dict[str, Any]) -> bool:
        """
        处理订单发货事件
        更新订单状态为已发货
        
        Args:
            store_domain (str): 店铺域名
            data (Dict[str, Any]): 订单数据
            
        Returns:
            bool: 处理结果
        """
        order_data = data.get("order", {})
        
        # 查询对应的本地订单
        order = self.db.exec(
            select(Order).where(Order.shopify_order_id == str(order_data["id"]))
        ).first()
        
        if order:
            # 更新订单状态为已发货
            order.status = OrderStatus.SHIPPED
            order.updated_at = datetime.utcnow()
            
            self.db.commit()
            logger.info(f"Shopify订单已发货: {order.order_number}")
        
        return True
    
    def _trigger_production(self, order: Order):
        """
        触发生产流程
        为已支付订单创建生产任务
        
        Args:
            order (Order): 订单对象
        """
        # 动态导入生产服务，避免循环导入
        from app.services.production_service import ProductionService
        production_service = ProductionService(self.db)
        production_service.create_production_job(order)
    
    def _verify_webhook_signature(self, store_domain: str, data: Dict[str, Any]) -> bool:
        """
        验证webhook签名
        确保接收到的webhook数据来自合法的Shopify店铺
        
        Args:
            store_domain (str): 店铺域名
            data (Dict[str, Any]): 包含签名和数据的webhook信息
            
        Returns:
            bool: 签名验证结果
        """
        # 查询店铺记录
        store = self.db.exec(
            select(ShopifyStore).where(ShopifyStore.shopify_domain == store_domain)
        ).first()
        
        if not store:
            return False
        
        # 获取签名和数据
        hmac_header = data.get("hmac", "")
        calculated_hmac = hmac.new(
            store.api_secret.encode('utf-8'),
            data.get("data", "").encode('utf-8'),
            hashlib.sha256
        ).hexdigest()
        
        # 安全比较签名
        return hmac.compare_digest(calculated_hmac, hmac_header)
    
    def _make_shopify_request(self, store: ShopifyStore, method: str, endpoint: str, data: Dict[str, Any] = None):
        """
        发送Shopify API请求
        
        Args:
            store (ShopifyStore): 店铺对象
            method (str): HTTP请求方法
            endpoint (str): API端点路径
            data (Dict[str, Any], optional): 请求数据
            
        Returns:
            Dict[str, Any]: API响应数据
            
        Raises:
            ValueError: 当HTTP方法不支持时抛出
            HTTPError: 当API请求失败时抛出
        """
        # 构建完整URL
        url = f"https://{store.shopify_domain}{endpoint}"
        headers = {
            'X-Shopify-Access-Token': store.access_token,
            'Content-Type': 'application/json'
        }
        
        # 根据请求方法发送不同类型的请求
        if method.upper() == "GET":
            response = requests.get(url, headers=headers, params=data)
        elif method.upper() == "POST":
            response = requests.post(url, headers=headers, json=data)
        elif method.upper() == "PUT":
            response = requests.put(url, headers=headers, json=data)
        elif method.upper() == "DELETE":
            response = requests.delete(url, headers=headers)
        else:
            raise ValueError(f"不支持的HTTP方法: {method}")
        
        # 检查响应状态
        response.raise_for_status()
        return response.json()